import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lenovo
 * Date: 2022-11-22
 * Time: 21:34
 */

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
//    json操作在get和post请求方法里都要使用,因此将这个对象写成类成员属性
    private ObjectMapper objectMapper = new ObjectMapper();

//    ////使用mysql,数据就不用在存储到内存里,因此  private List<Message> messageList = new ArrayList<>();就不需要了
////    创建一个顺序表,用于保存浏览器提交的message
////    messageList会随着服务器重启就没了
//    private List<Message> messageList = new ArrayList<>();
//    让页面获取到数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        显示的声明当前响应数据格式不要让客户端去猜!!!
        resp.setContentType("application/json; charset=utf8");
//        构造json:把messageList转换成json格式发挥给浏览器即可
//        使用数据库,messageList不用了,换成load
        try {
            resp.getWriter().write(objectMapper.writeValueAsString(load()));
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
//页面提交数据给服务器
//    就需要读取浏览器发来的请求,其中post的正文都放在body里,这里body采用json格式
//    因此要读去body里的json字符串,就得使用第三方库jackson
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1.获取body里的内容并解析
//        使用readvalue将请求里的输入流里的body读取出来,并根据body里的键值对的类对象实例化一个对象
    Message message = objectMapper.readValue(req.getInputStream(),Message.class);
//    2.把这个message保存一下,简单的办法是存在内存里:创建一个顺序表
////        使用数据库保存,messageList.add(message);用不到了
//        messageList.add(message);
        try {
            save(message);
        } catch (SQLException e) {
            e.printStackTrace();
        }
//        3.返回成功,状态码200
        resp.setStatus(200);
//        4.打印日志
        System.out.println("提交成功: from="+message.getFrom()+"to="+message.getTo()+"messag="+message.getMessage());
    }

    private List<Message> load() throws SQLException {
    //从数据库查询数据
        //1.先有一个数据源 datasource
//        Datasource是jdbc里的，提供给各种数据库：向上转型
//       单例模式
        DataSource dataSource = DBUtil.getInstanceDataSource();
//        url是mysql里独有的
////        这里要将dataSource转换成MysqlDataSource：向下转型
//        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java105?characterEncoding=utf8&useSSL=false");
////        用户名
//        ((MysqlDataSource)dataSource).setUser("root");
////        密码,没有密码使用空字符串
//        ((MysqlDataSource)dataSource).setPassword("");

        //2.建立连接
//        注意connection是jdbc里的（java.sql）
//        有异常,直接抛出即可
        Connection connection = dataSource.getConnection();

        //3.构造sql语句
//        PreparedStatement也是jdbc里的(java.sql)
        String sql = "select * from messagewall";
//         PreparedStatement类进行替换
        PreparedStatement statement = connection.prepareStatement(sql);

        //4.执行sql
//        executeQuery返回的是一个集合 数据表
        ResultSet resultSet = statement.executeQuery();


        //5.遍历resultset这个集合
        List<Message> messageList = new ArrayList<>();
        while(resultSet.next()) {

            // 每次循环, 就能够获取到 resultSet 中的一行. 进一步的就可以拿到每一列!!
            // getXXX 也是有一系列方法的. 会根据要取的数据的类型, 来灵活决策.
            Message message = new Message();
//            从一行数据里取出 from to message这三列加到message的成员变量里
//            from这一列
            message.setFrom(resultSet.getString("from"));
            message.setTo(resultSet.getString("to"));
            message.setMessage(resultSet.getString("message"));
//            在将message添加到messageList里
            messageList.add(message);

        }

        //6.关闭连接
        statement.close();
        connection.close();
//        关闭连接后返回messageList即可
        return messageList;

    }


    private void save(Message message) throws SQLException {
//        把数据保存到数据库中
        //1.先有一个数据源 datasource
//        Datasource是jdbc里的，提供给各种数据库：向上转型
//        DataSource dataSource = new MysqlDataSource();
//        单例模式
        DataSource dataSource = DBUtil.getInstanceDataSource();
//        url是mysql里独有的
//        这里要将dataSource转换成MysqlDataSource：向下转型
//        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java105?characterEncoding=utf8&useSSL=false");
////        用户名
//        ((MysqlDataSource)dataSource).setUser("root");
////        密码,没有密码使用空字符串
//        ((MysqlDataSource)dataSource).setPassword("");

        //2.建立连接
//        注意connection是jdbc里的（java.sql）
//        有异常,直接抛出即可
        Connection connection = dataSource.getConnection();

        //3.构造sql语句
//        PreparedStatement也是jdbc里的(java.sql)
        String sql = "insert into messagewall values(?,?,?)";
//         PreparedStatement类进行替换
        PreparedStatement statement = connection.prepareStatement(sql);
//        使用get系列的方法,根据?顺序实现替换
        statement.setString(1,message.getFrom());
        statement.setString(2,message.getTo());
        statement.setString(3,message.getMessage());

        //4.执行sql
        int ret = statement.executeUpdate();
//        打印结果
        System.out.println("ret="+ret);

        //5.关闭连接
        statement.close();
        connection.close();

    }
}
